"""
定义一些个工具函数：
1、cookies提取购物车
2、构建cookie购物车数据
3、获取redis购物车数据
4、合并购物车数据 —— 用户一旦登陆，我们把cookie购物车合并到redis中
"""

import base64, pickle
from django_redis import get_redis_connection

def merge_cart_cookie_to_redis(request, user, response):
    """
    合并购物车数据
    :param request: 为了获取cookie 购物车数据
    :param user: 根据用户id拼接到redis 名称获取该用户到redis 购物车数据
    :param response:  为了使用response 删除原有cookie购物车数据
    :return: 返回响应对象
    """

    # 1 提取cookie 购物车数据
    # {14: {"count": 5, "selected": True}} or {}
    cookie_cart = get_carts_from_cookies(request)

    # 2.提取redis 购物车数据
    request.user = user   # 动态语言的魅力
    # redis_cart = {b"14": b"5"}
    # redis_selected = {b"14"}
    redis_cart, redis_selected = get_redis_cart(request)

    # 3.合并： cookie合并到redis
    # 3.1 cookie中所有的商品(不管是否选中)都合并到redis
     # 3.2 合并之后删除cookie购物车
     # 3.3 cookie中存在到商品如果在redis中则覆盖redis
     # 3.4 cookie中不存在的商品则新写入redis

    conn = get_redis_connection('carts')
    p1 = conn.pipeline()

    # {14: {"count": 5, "selected": True}}
    for sku_id, item in cookie_cart.items():
        # sku_id: 14
        # item: {"count": 5, "selected": True}
        p1.hset('carts_%s' % user.id, sku_id, item['count'])
        if item['selected']:
            p1.sadd('selected_%s' % user.id, sku_id)
        else:
            p1.srem('selected_%s' % user.id, sku_id)

    p1.execute()

    # 4.通过response 删除cookie 购物车
    response.delete_cookie('carts')
    return response




def get_carts_from_cookies(request):
    """获取cookie 中的购物出数据"""
    carts_from_cookies = request.COOKIES.get('carts')
    if carts_from_cookies:
        # 1.先base64解码
        cart_dict = base64.b64decode(carts_from_cookies.encode())
        # 2.再pickle解码
        cart_dict = pickle.loads(cart_dict)
        return cart_dict
    else:
        return {}


def get_cookie_cart_data(cookie_cart):
    """
    使用pickle和base64对购物车字典数据，编码得出存储到cookie中的字符串
    :param cookie_cart: 购物车字典
    :return: 经过pickle 和 base64编码后的字符串
    """
    return base64.b64encode(
        pickle.dumps(cookie_cart)
    ).decode()


def get_redis_cart(request):
    user_id = request.user.id
    redis_cart =None
    redis_delected = None

    conn = get_redis_connection('carts')

    # 读取购物车数据
    # redis_cart = {b"14": b"5"} 或者 返回None
    redis_cart = conn.hgetall('carts_%s' % user_id)

    # 读取选中信息
    # redis_selected={b"14"} 后者 返回None
    redis_delected = conn.smembers('selected_%s' % user_id)

    if not redis_cart:
        redis_cart = {}   # 如果缓存不存在，则返回空字典

    if not redis_delected:
        redis_delected = set()  # 如果缓存不存在，则返回空字典

    return redis_cart, redis_delected
